﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharpPcap;
using SharpPcap.WinPcap;
using PacketDotNet;
using System.Net;
using SharpPcap.LibPcap;
using System.IO;

namespace MyNetMonitor
{
    public partial class AnalyzeForm : Form
    {
        List<RawCapture> pList;
        List<PacketSummary> psl = new List<PacketSummary>();
        public AnalyzeForm()
        {
            InitializeComponent();
            pList = new List<RawCapture>();
        }
        public AnalyzeForm(List<RawCapture> packetList)
        {
            InitializeComponent();
            this.pList = packetList;
            BindDataGrid();
        }
        public void BindDataGrid()
        {
            foreach (RawCapture rp in pList)
            {
                PacketSummary ps = new PacketSummary();
                ps.ArrivalTime = rp.Timeval;
                TcpPacket tcp = TcpPacket.GetEncapsulated(Packet.ParsePacket(rp.LinkLayerType, rp.Data));
                IpPacket ip = IPv4Packet.GetEncapsulated(Packet.ParsePacket(rp.LinkLayerType, rp.Data));
                ps.SourceAddress = ip.SourceAddress.ToString();
                ps.SourcePort = tcp.SourcePort.ToString();
                ps.DestAddress = ip.DestinationAddress.ToString();
                ps.DestPort = tcp.DestinationPort.ToString();
                ps.Length = rp.Data.Length;
                psl.Add(ps);
            }
            dataGridView1.DataSource = psl.ToList();
            dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            dataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            dataGridView1.Columns[4].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
            dataGridView1.Columns[5].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
        }

        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            RawCapture rp = pList[e.RowIndex];
            TcpPacket tcp = TcpPacket.GetEncapsulated(Packet.ParsePacket(rp.LinkLayerType, rp.Data));
            IpPacket ip = IPv4Packet.GetEncapsulated(Packet.ParsePacket(rp.LinkLayerType, rp.Data));
            byte[] data = new byte[tcp.Bytes.Length-tcp.DataOffset];
            int s = 0;
            foreach (byte b in tcp.Bytes.Skip(tcp.DataOffset))
            {
                data[s] = b;
                s++;
            }
            BindTextBoxHex(data);
            BindTextBoxText(data);
        }
        private void BindTextBoxHex(byte[] data)
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte b in data)
            {
                if (b < 16)
                {
                    sb.Append("0");
                }
                sb.Append(b.ToString("X"));
                sb.Append(" ");
            }
            tbBinary.Text = sb.ToString();
        }
        private void BindTextBoxText(byte[] data)
        {
            if (clbEncoding.SelectedItem == null) return;
            StringBuilder sb = new StringBuilder();
            if (clbEncoding.SelectedItem.ToString() == "ASCII")
            {
                foreach (byte b in data)
                {
                    if ((b >= 32 && b <= 93) || b >= 97 && b <= 126)
                    {
                        sb.Append(" ");
                        sb.Append(Encoding.ASCII.GetString(new byte[] { b }));
                    }
                    else
                    {
                        sb.Append("??");
                    }
                    sb.Append(" ");
                }
            }
            else if (clbEncoding.SelectedItem.ToString() == "UTF-8")
            {
                int i = 0;
                do
                {
                    if (data[i] < 0x80)
                    {
                        byte b = data[i];
                        if ((b >= 32 && b <= 93) || b >= 97 && b <= 126)
                        {
                            sb.Append(Encoding.ASCII.GetString(new byte[] { b }));
                        }
                        else
                        {
                            sb.Append("??");
                        }
                        sb.Append(" ");
                        i++;
                        continue;
                    }
                    else if (data[i] < 0xC0)
                    {
                        sb.Append("??");
                        sb.Append(" ");
                        i++;
                        continue;
                    }
                    else if (data[i] < 0xE0)
                    {
                        if (i < data.Length - 1 && (data[i + 1] & 0xC0) == 0x80)
                        {
                            sb.Append(Encoding.UTF8.GetString(new byte[] { data[i], data[i + 1] }));
                            i += 2;
                            continue;
                        }
                        else
                        {
                            sb.Append("?? ??");
                            i += 2;
                            continue;
                        }
                    }
                    else if (data[i] < 0xF0)
                    {
                        if (i < data.Length - 2 && (data[i + 1] & 0xC0) == 0x80 && (data[i + 2] & 0xC0) == 0x80)
                        {
                            sb.Append(Encoding.UTF8.GetString(new byte[] { data[i], data[i + 1], data[i + 2] }));
                            i += 3;
                            continue;
                        }
                        else
                        {
                            sb.Append("?? ?? ??");
                            i += 3;
                            continue;
                        }
                    }
                    else
                    {
                        sb.Append("??");
                        i += 1;
                        continue;
                    }
                } while (i < data.Length);
            }
            else if (clbEncoding.SelectedItem.ToString() == "GBK")
            {
                sb.Append(Encoding.GetEncoding("GBK").GetString(data));
            }
            tbText.Text = sb.ToString();
        }

        private void clbEncoding_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            if (clbEncoding.CheckedItems.Count > 0)
            {
                for (int i = 0; i < clbEncoding.Items.Count; i++)
                {
                    if (i != e.Index)
                    {
                        this.clbEncoding.SetItemCheckState(i,
                        System.Windows.Forms.CheckState.Unchecked);
                    }
                }
            } 
        }

        private void clbEncoding_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

    }
}
